﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CloudStorageLight.WpfClient
{
    /// <summary>
    /// Blobのアクセストークン
    /// 
    /// [ロール名]:rwmcの形式
    /// r:読み込み
    /// w:書き込み
    /// m:変更
    /// c:コントロール
    /// 
    /// </summary>
    public class BlobAccessToken
    {
        /// <summary>
        /// ロール
        /// </summary>

        public string Role
        {
            get { return _role; }
            set 
            {
                if (value != null)
                {
                    _role = value.ToLower().Trim();
                }
                else
                {
                    _role = value;
                }
            }
        }
        private string _role;

        /// <summary>
        /// 読み込み可能
        /// </summary>
        public bool CanRead
        {
            get { return _CanRead; }
            set { _CanRead = value; Token = FormatToken(); }
        }
        private bool _CanRead;

        /// <summary>
        /// 書き込み可能
        /// </summary>
        public bool CanWrite
        {
            get { return _CanWrite; }
            set { _CanWrite = value; Token = FormatToken(); }
        }
        private bool _CanWrite;


        /// <summary>
        /// 上書き可能
        /// </summary>
        public bool CanModify
        {
            get { return _Modify; }
            set { _Modify = value; Token = FormatToken(); }
        }
        private bool _Modify;


        /// <summary>
        /// コントロール可能
        /// </summary>
        public bool CanControl
        {
            get { return _CanControl; }
            set { _CanControl = value; Token = FormatToken(); }
        }
        private bool _CanControl;

        /// <summary>
        /// セキュリティトークン
        /// </summary>
        public string Token { get; private set; }


        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="token"></param>
        public BlobAccessToken(string token)
        {
            this.Token = token;
            ParseToken(token);
        }

        /// <summary>
        /// トークンのパース
        /// </summary>
        /// <param name="token"></param>
        private void ParseToken(string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                var items = token.Split(':');
                if (items.Length > 2) throw new ArgumentException("token");
                Role = items[0];
                if (items.Length > 1)
                {
                    SetMode(items[1]);
                }
                else
                {
                    SetMode("");
                }
                
            }
        }

        /// <summary>
        /// 指定のモードでアクセス可能か
        /// </summary>
        /// <param name="mode"></param>
        /// <returns></returns>
        public bool CanAccess(string mode)
        {
            mode = mode.ToLower();
            if (mode.IndexOf("r") >= 0 && !CanRead) return false;
            if (mode.IndexOf("w") >= 0 && !CanWrite) return false;
            if (mode.IndexOf("m") >= 0 && !CanModify) return false;
            if (mode.IndexOf("c") >= 0 && !CanControl) return false;
            return true;
        }

        /// <summary>
        /// モードの設定
        /// </summary>
        /// <param name="rwc"></param>
        public void SetMode(string rwc)
        {
            if (string.IsNullOrEmpty(rwc)) return;
            rwc = rwc.ToLower();
            CanRead = (rwc.IndexOf('r') >= 0);
            CanWrite = (rwc.IndexOf('w') >= 0);
            CanModify = (rwc.IndexOf('m') >= 0);
            CanControl = (rwc.IndexOf('c') >= 0);
        }
        private string FormatToken()
        {
            var formated = Role + ":";
            if (CanRead) formated += "r";
            if (CanWrite) formated += "w";
            if (CanModify) formated += "m";
            if (CanControl) formated += "c";
            return formated;
        }
    }
}
